<template>
  <section
    ref="canvas"
    :style="{ width, height }"
  />
  <van-slider
    v-if="customScroll"
    v-model="sliderValue"
    :style="{
      ...sliderStyle,
      margin: '12px auto'
    }"
    :max="sliderMax"
    :step="zoomSteps"
    :bar-height="6"
    @change="handleSliderChange"
  >
    <template #button>
      <section class="base-slider__button-wrapper">
        <span class="line" />
        <span class="line" />
        <span class="line" />
      </section>
    </template>
  </van-slider>
</template>

<script setup lang="ts" name="AppChart">
import {
  ref, watch, onUnmounted,
  nextTick,
} from 'vue';

import { useDebounceFn } from '@vueuse/core';
import * as echarts from 'echarts';

const props = defineProps({
  autoResize: {
    type: Boolean,
    default: false,
  },
  /**
     * @description: 是否使用自定义的缩放组件相关行为，如果使用，必须引入数据区域缩放组件后才能使用。
     */
  customScroll: {
    type: Boolean,
    default: false,
  },
  /**
     * @description: 缩放组件的步长，默认为10
     */
  zoomSteps: {
    type: Number,
    default: 10,
  },
  width: {
    type: String,
    default: '100%',
  },
  height: {
    type: String,
    default: '100%',
  },
  options: {
    type: Object,
    default: () => ({}),
  },
  /**
     * @description: 缩放组件的样式，一般用于设置缩放组件的宽度
     */
  sliderStyle: {
    type: Object,
    default: () => ({
      width: '50%',
    }),
  },
});

const canvas = ref(null);
let instance: any;

const resizeHandle = () => {
  if (instance) {
    instance.showLoading();
    instance.resize();
    instance.hideLoading();
  }
};

const debounceFunc = useDebounceFn(resizeHandle, 300);

const initCharts = () => {
  if (!canvas.value) {
    return;
  }
  instance = echarts.init(canvas.value);
  instance.setOption(props.options);
  if (props.autoResize) {
    window.addEventListener('resize', debounceFunc);
  }
};

const sliderValue = ref(0);
const sliderMax = ref(100);
const handleSliderChange = (val:number) => {
  const s = val;
  const e = val + props.zoomSteps - 1;

  instance.dispatchAction({
    type: 'dataZoom',
    batch: [
      {
        type: 'dataZoom',
        dataZoomIndex: 0,
        startValue: s,
        endValue: e,
      }
    ],
  });
};

const getInstance = () => instance;

watch(
  () => props.options,
  (val) => {
    if (instance) {
      if (props.customScroll) {
        sliderValue.value = 0;
        instance.setOption({
          ...val,
          dataZoom: [
            {
              type: 'slider',
              show: false,
            }
          ],
        }, true);

        instance.dispatchAction({
          type: 'dataZoom',
          batch: [
            {
              type: 'dataZoom',
              dataZoomIndex: 0,
              startValue: 0,
              endValue: props.zoomSteps - 1,
            }
          ],
        });
        sliderMax.value = val.series?.[0]?.data?.length || 100; // 计算x轴数据的最大值
      } else {
        instance.setOption(val, true);
      }
    } else {
      nextTick(() => {
        initCharts();
      });
    }
  },
  {
    immediate: true,
    deep: true,
  }
);

onUnmounted(() => {
  if (props.autoResize) {
    window.removeEventListener('resize', debounceFunc);
  }
  if (instance) {
    instance.dispose();
  }
});

defineExpose({
  getInstance,
});
</script>

<style lang="scss" scoped>
.base-slider__button-wrapper {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 14px;
  padding: 0 4px;
  background-color: #fff;
  border: 1px solid #9fbfff;
  border-radius: 7px;

  .line {
    display: flex;
    width: 1px;
    height: 6px;
    margin: 0 1px;
    background-color: #eee;
    border-radius: 3px;
  }
}
</style>
